﻿using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Mvc;
using Polly;
using Microsoft.AspNetCore.Authorization;

namespace OAuthClient.Server
{
    public class AuthClient
    {
        public readonly TokenManage _tokenManage;

        public readonly HttpClient _httpClient;

        public AuthClient(TokenManage tokenManage, HttpClient httpClient)
        {
            _tokenManage = tokenManage;
            _httpClient = httpClient;
        }

        public async Task<string> GetInfo(string name)
        {
            var tokeninfo = _tokenManage.Get(name);
            var request = new HttpRequestMessage(HttpMethod.Get, "https://localhost:5005/oauth/info");

            request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", tokeninfo.AccessToken);
            request.Headers.Add("name", name);

            var result = await _httpClient.SendAsync(request);

            var content = await result.Content.ReadAsStringAsync();

            return content;
        }

        public static IAsyncPolicy<HttpResponseMessage> HandleUnAuthorized(
            IServiceProvider serviceProvider,
            HttpRequestMessage request
            )
        {
            return Policy.HandleResult<HttpResponseMessage>(resp =>
            {
                return resp.StatusCode == System.Net.HttpStatusCode.Unauthorized;
            }).RetryAsync(1, async (e, attemp) =>
            {
                var scope = serviceProvider.CreateScope();
                var token = scope.ServiceProvider.GetRequiredService<TokenManage>();

                var fresh = scope.ServiceProvider.GetRequiredService<Refresh>();

                var name = request.Headers.GetValues("name").First();

                var tokeninfo = token.Get(name);
                var result = await fresh.RefreshToken(tokeninfo);

                token.Save(name, new TokenManage.TokenInfo(result.AccessToken, result.RefreshToken, Convert.ToDateTime(result.ExpiresIn)));

                request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", result.AccessToken);

            });
        }
    }
}
